<!--
@function: 这是一个表格搜索组件
@author:HYS
@description:
1 结构：这个组件包含两个部分，一个是input框和后面两个按钮（清空和搜索），一个是前面的下拉菜单，
其中的菜单项为表格的列，可选，并可以对各个列单独指定关键字。

2 设置：
    tableColumns: Array, 表格列数组,构建表格时候的列数组，用来构造组件
      prop:String,字段代号
      label:String,汉字名称
      outOfSearch:Boolean 可选项, 不使用字段进行搜索
      type:String,可选项, 对应元素的组件类型
          date->日期选择器,
          time->时间选择器,
          select->下拉选择器,
          不写则为默认的文本框
      options:String,可选项, 当type=select时， 
          value:String,显示的文字
          id:String,选中的值
    size:String, 默认值为mini，搜索框和下拉框的大小
    usePagination:Boolean, 使用分页，会添加分页参数
    currentPage:Number, 分页参数，当前页 
    pageSize:Number, 默认值25，每页条数
    inputLabelSearchMode:Boolean, 启用输入标签搜索模式，默认值为false，当设置为true时，会使得input变为可以填写多个标签的select

3 行为：
点击清空，可以清空包括菜单项在内所有input的值；
点击搜索可以触发搜索事件，并发送参数；
各个菜单项可选，选中后可以按照指定的列进行搜索

4 其他：这个组件有两种模式，精确和非精确，填写了任何下拉菜单列中的值时，视为使用精确查
找，否则视为非精确查找。
非精确查找，传递的参数是:精确查找开关isAccurate，
                      对于所有列的关键字searchText，
                      所选中的要查询的列checkedColumns
精确查找，传递的参数是：精确查找开关isAccurate，
                      所选中列的一组关键字键值对paramPairs

@modify:胡杨升 2018-9-19
添加了inputLabelSearchMode:Boolean属性，默认位false，当设置为true时，可以把input框变为可以输入多个标签的select框，也就是传送给后台同时查询多个值

TODO 目前checkbox选中获取值是中文label，不能得到对应的prop
-->
<template>
<div class="grid-search">
  <el-input v-model="searchText" placeholder="请输入" clearable :size="size">
    <el-popover slot="prepend" placement="bottom" trigger="click">
      <el-button slot="reference">
        查找<i class="el-icon-arrow-down el-icon--right"></i>
      </el-button>
      <div v-if="tableColumns.length > 0">
        <el-checkbox label="选择所有" v-model="checkAll" @change="handleCheckAllChange"
        style="height:30px;border-color:#000;border:5px;">
        </el-checkbox>
        <el-checkbox-group v-model="checkedColumns" @change="handleCheckedColumnsChange">
          <template v-for="col in this.tableColumns">
            <el-row :key="col.label" v-if="!col.outOfSearch" style="display:flex;">
              <el-col :span="8" style="margin:auto;">
                <el-checkbox :label="col.label" :key="col.prop" :name="col.prop" >
                </el-checkbox>
              </el-col>
              <el-col :span="16">
                <el-date-picker v-if="col.type === 'date' "
                  v-model="searchTexts[col.prop]"
                  type="daterange" range-separator="-" start-placeholder="开始" end-placeholder="结束" 
                  :picker-options="datePickerOption" style="width:100%;" format="yyyy-MM-dd" size="mini" value-format="timestamp">
                </el-date-picker>
                <el-time-picker v-else-if="col.type === 'time' "
                  is-range
                  v-model="searchTexts[col.prop]"
                  value-format="HH:mm:ss"
                  type="daterange" range-separator="-"  start-placeholder="开始" end-placeholder="结束"
                  style="width:100%;" size="mini">
                </el-time-picker> 
                <el-select v-else-if="col.type === 'select'" v-model="searchTexts[col.prop]" placeholder="请选择"
                clearable style="width:100%;" size="mini">
                  <el-option v-for="option in col.options" :key="option.id" :value="option.id" :label="option.value"></el-option>
                </el-select>
                <template v-else>
                  <el-select v-if="inputLabelSearchMode" size="mini" class="input-label-select" popper-class="input-label-select-popper"
                    v-model="searchTexts[col.prop]" multiple allow-create filterable default-first-option>
                  </el-select>
                  <el-input v-else v-model="searchTexts[col.prop]" clearable placeholder="输入关键字" size="mini">
                  </el-input>
                </template>
              </el-col>
            </el-row>
          </template>
        </el-checkbox-group>
      </div>
    </el-popover>
    <el-tooltip slot="append" class="item" effect="light" content="清空文字" placement="top-start">
      <el-button @click="onClearClick" icon="el-icon-circle-close-outline" size="mini"></el-button>
    </el-tooltip>
    <el-tooltip slot="append" class="item" effect="light" content="点击加载表格数据" placement="top-start">
      <el-button @click="onSearchClick" icon="el-icon-search" size="mini"></el-button>
    </el-tooltip>
  </el-input>
</div>
</template>
<script>
// import datepicker from "./tplcol/Datepicker.vue";
// 列的属性有text，bool，date，number等

// 获取列名称数组
var takeColumnNames = function(tableColumns) {
  var cols = [];
  tableColumns.forEach(col => {
    cols.push(col.label);
  });
  return cols;
};

// 精确搜索文字的初始化
var searchTextsInit = (tableColumns) => {
  var ret = {};
  tableColumns.forEach((col) => {
    if(col.type=="date"){
      ret[col.prop] = null;
    }else{
      ret[col.prop] = "";
    }
    
  });
  return ret;
}

// 日期选择的快捷方式
var shortcuts = [
  {
    text: '近一周',
    onClick(picker) {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
      picker.$emit('pick', [start, end]);
    }
  }, {
    text: '近两周',
    onClick(picker) {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 14);
      picker.$emit('pick', [start, end]);
    }
  }, {
    text: '近一个月',
    onClick(picker) {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
      picker.$emit('pick', [start, end]);
    }
  }, {
    text: '近两个月',
    onClick(picker) {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 60);
      picker.$emit('pick', [start, end]);
    }
  }, {
    text: '近三个月',
    onClick(picker) {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
      picker.$emit('pick', [start, end]);
    }
  }
];

export default {
  name: "grid-search",
  props: {
    tableColumns: {
      type: Array,
      default: []
    },
    size:{
      type:String,
      default:"mini"
    },
    usePagination:{
      typ:Boolean,
      default:true
    },
    currentPage:{
      type:Number,
      default:1
    },
    pageSize:{
      type:Number,
      default:25
    },
    inputLabelSearchMode:{
      type:Boolean,
      default:false
    }
  },
  // components:[datepicker],
  computed: {
    isSearchTextsDirty: { // 精确搜索文字中是否有值
      get: function() {
        var me = this;
        for (var key in me.searchTexts) {
          if (me.searchTexts.hasOwnProperty(key)) {
            // 在标签输入方式下，都是数组
            if(me.inputLabelSearchMode){
              if(me.searchTexts[key] instanceof Array && (me.searchTexts[key].length > 0)){
                return true;
              }
            }else{
              //text初始为""，date初始为null
              if (me.searchTexts[key] !== "" && me.searchTexts[key] !== null) {
                return true;
              }
            }
            
          }
        }
        return false;
      }
    }
  },
  methods: {
    handleCheckAllChange(val) { // 选中所有列
      var me = this;
      me.checkedColumns = val ? takeColumnNames(me.tableColumns) : [];
      this.$emit("checkall-changing", val);
    },
    handleCheckedColumnsChange: function(value) { // 选中列改变
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.tableColumns.length;

      this.$emit("checkcolumns-changing", value);
    },
    clearSearchTexts: function() { // 清空精确搜索文字
      var me = this;
      for (var key in me.searchingTextCache) {
        if (me.searchingTextCache.hasOwnProperty(key)) {
          me.searchingTextCache[key] = "";
        }
      }
    },
    onClearClick: function() { // 按钮响应-清空文字
      // 搜索文字，还有精确搜索文字
      this.searchText = "";
      this.clearSearchTexts();
    },
    onSearchClick: function() { // 按钮响应-搜索
      var me = this;
      // 如果searchMenu的searchingTextCache中有值，则是精确查找，否则是模糊查找
      me.isAccurate = me.isSearchTextsDirty;
      // 这里组织参数 冒泡搜索事件
      var retParams = { };
      if(me.usePagination) {
        // retParams.currentPage = this.currentPage;
        // retParams.pageSize = this.pageSize;
        retParams.page = me.currentPage;
        retParams.size = me.pageSize;
      }
      if (me.isAccurate) {
        // 在传送到后台之前，调整参数格式，把数组变为JSON字符串
        let finalSearchTexts = {};
        for (let prop in me.searchTexts) {
          if (me.searchTexts.hasOwnProperty(prop)) {
           if(me.searchTexts[prop] instanceof Array){
             finalSearchTexts[prop] = JSON.stringify(me.searchTexts[prop]);// 与后台约定，转换成json字符串
           }else{
             finalSearchTexts[prop] = me.searchTexts[prop];
           }
          }
        }
        retParams = Object.assign(retParams, { //精确搜索时，是发送一个参数组
          isAccurate: this.isAccurate,
          paramPairs: finalSearchTexts
        });
      } else {
        retParams = Object.assign(retParams, { //不精确搜索时，是发送所选中的域和单一的文本关键字
          isAccurate: this.isAccurate,
          fields: this.checkedColumns,
          query: this.searchText
        });
      }
      this.$emit('searching', retParams);
    }
  },
  data() {
    return {
      isAccurate: false, // 是否精确查找
      searchText: "", // 搜索文字
      checkAll: true, // 是否全选-列
      checkedColumns: [], // 选中的列
      searchTexts: {}, // 精确搜索文字
      datePickerOption: {// 日期选择框的快捷选择配置
        shortcuts: shortcuts
      }
    };
  },
  created: function() {
    // 初始化-全选
    this.handleCheckAllChange(true);
    // 搜索字段文字
    this.searchTexts = searchTextsInit(this.tableColumns);
  }
}
</script>
<style lang="scss">
.grid-search{
  .column-menu-item {
      display: inline-flex;
      text-align: center;
      vertical-align: middle;
  }
  // .input-label-select{

  //   input{
  //     height:28px;
  //   }
  // }

}

.input-label-select-popper{
  display: none;
}
</style>
